import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ImageDownloaderWithProxy {

    private static final String PICTURE_TYPE_JPG = ".jpg";
    private static final String PICTURE_TYPE_PNG = ".png";
    private static final String SLASH = "/";
    
    public static final String IMAGE_DOWNLOAD_INFO_PLACE = "D:\\CodeSpace\\IdeaSpace\\my-test\\Test\\src\\main\\java\\imageDownloadInfo";
    

    public static void main(String[] args) throws Exception {
        Stream<String> imageDownloadInfo = Files.lines(Paths.get(IMAGE_DOWNLOAD_INFO_PLACE));
        List<String> imageDownloadInfos = imageDownloadInfo.collect(Collectors.toList());
        String cutImageUrl = getCutImageUrl(imageDownloadInfos.get(1));
        // 开始页号
        Integer beginPage = Integer.valueOf(imageDownloadInfos.get(2));
        // 结束页号,默认为300
        Integer endPage = Integer.valueOf(imageDownloadInfos.get(3));
        // .JPG .PNG
        List<String> pictureTypeList = Arrays.asList(imageDownloadInfos.get(4).split(" "));
        // 下载目录位置
        String mainFileName = "F:\\shit\\" + imageDownloadInfos.get(0);
        downloads(mainFileName, cutImageUrl, pictureTypeList, beginPage, endPage);
    }
    

    private static String getCutImageUrl(String imageUrl) {
        int lastPart = imageUrl.lastIndexOf(SLASH);
        return imageUrl.substring(0, lastPart + 1);
    }

    public static void downloads(String mainFileName, String imageUrl, List<String> pictureType, Integer beginPage, Integer endPage) throws Exception {
        File file = new File(mainFileName);
        // 如果不存在则创建
        boolean newDownloadSign = file.mkdir();
        // 全新下载
        if (newDownloadSign) {
            downloadDetail(mainFileName, imageUrl, pictureType, beginPage, endPage);
        } else {
            // 增量下载
            List<File> files = Arrays.stream(file.listFiles()).sorted((f1, f2) -> {
                // 获取文件名并将其转换为整数进行比较
                int num1 = Integer.parseInt(f1.getName().replace(PICTURE_TYPE_JPG, "").replace(PICTURE_TYPE_PNG, ""));
                int num2 = Integer.parseInt(f2.getName().replace(PICTURE_TYPE_JPG, "").replace(PICTURE_TYPE_PNG, ""));
                return Integer.compare(num1, num2);
            }).collect(Collectors.toList());
            // 获取最后一个,删除
            int toDeleteFileIndex = files.size() - 1;
            File toDeleteFile = files.get(toDeleteFileIndex);
            boolean deleteSuccess = toDeleteFile.delete();
            if (deleteSuccess) {
                downloadDetail(mainFileName, imageUrl, pictureType, toDeleteFileIndex + 1, endPage);
            }
        }
    }

    private static void downloadDetail(String mainFileName, String imageUrl, List<String> pictureType, Integer beginPage, Integer endPage) throws Exception {
        System.out.println("=================开始下载=================");
        // 页数循环
        for (int i = beginPage; i <= endPage; i++) {
            Integer pictureTypeCount = 0;
            // 类型循环
            // 当前图片类型
            for (int j = 0; j < pictureType.size(); j++) {
                pictureTypeCount = j;
                String currentPictureTypeString = pictureType.get(j);
                String downloadUrl = imageUrl + i + currentPictureTypeString;
                try {
                    downloadWithDeal403(downloadUrl, mainFileName + "\\" + i + currentPictureTypeString);
                    System.out.println("当前成功下载页数为:" + i + currentPictureTypeString);
                    // 成功跳出类型循环
                    break;
                } catch (Exception e) {
                    // 如果多种图片类型都获取失败，则程序终止,目前是2，png和jpg
                    if (Objects.equals(pictureTypeCount, pictureType.size() - 1)) {
                        throw new Exception("类型为:" + pictureType + ",结束页数为:" + i);
                    }
                    // 正常类型未识别就打印一下失败就行
                    System.out.println("当前失败下载页数为:" + i + currentPictureTypeString + ",失败原因为:" + e);
                }
            }
        }
        System.out.println("=================结束下载=================");
    }

    public static void downloadWithDeal403(String imageUrl, String destinationFile) throws IOException {
        // 设置代理服务器信息
        String proxyHost = "127.0.0.1";
        int proxyPort = 10809;
        String proxyUser = null; // 如果代理服务器需要验证
        String proxyPassword = null; // 如果代理服务器需要验证
        try {
            URL url = new URL(imageUrl);
            // 创建代理服务器对象
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
            // 打开连接时指定代理
            URLConnection conn = url.openConnection(proxy);
            // 如果代理服务器需要验证，则设置认证信息
            if (proxyUser != null && proxyPassword != null) {
                String auth = proxyUser + ":" + proxyPassword;
                String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
                conn.setRequestProperty("Proxy-Authorization", "Basic " + encodedAuth);
            }
            conn.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            InputStream inputStream = conn.getInputStream();
            OutputStream outputStream = new FileOutputStream(destinationFile);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
//            e.printStackTrace();
            throw e;
        }
    }

}
